// Copyright © SixtyFPS GmbH <info@slint.dev>
// SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-Slint-Royalty-free-2.0 OR LicenseRef-Slint-Software-3.0


import { MaterialPalette, MaterialFontSettings, Elevation, Icons, MaterialSizeSettings } from "styling.slint";
import { ListItem, StateLayer } from "components.slint";
import { ComboBoxBase } from "../common/combobox-base.slint";
import { ScrollView } from "./scrollview.slint";

export component ComboBox {
    in property <[string]> model <=> base.model;
    in property <bool> enabled <=> base.enabled;
    out property <bool> has-focus <=> base.has-focus;
    in-out property <int> current-index <=> base.current-index;
    in-out property <string> current-value <=> base.current-value;

    callback selected <=> base.selected;

    property <int> visible-items: min(6, model.length);

    min-width: max(160px, layout.min-width);
    min-height: max(22px, layout.min-height);
    horizontal-stretch: 1;
    vertical-stretch: 0;
    forward-focus: base;
    accessible-role: combobox;
    accessible-enabled: root.enabled;
    accessible-expandable: true;
    accessible-expanded: base.popup-has-focus;
    accessible-value <=> root.current-value;
    accessible-action-expand => { base.show-popup(); }

    states [
        disabled when !root.enabled : {
            background.border-color: MaterialPalette.control-foreground;
            background.opacity: 0.38;
            label.opacity: 0.38;
            icon.opacity: 0.38;
        }
        focused when root.has-focus : {
            background.border-width: 2px;
            background.border-color: MaterialPalette.accent-background;
            label.color: MaterialPalette.accent-background;
            icon.colorize: MaterialPalette.accent-background;
        }
    ]

    base := ComboBoxBase {
        width: 100%;
        height: 100%;

        show-popup => {
            popup.show();
        }
        close-popup => {
            popup.close();
        }
    }

    background := Rectangle {
        width: 100%;
        height: 100%;
        border-radius: 4px;
        border-width: 1px;
        border-color: MaterialPalette.border;
    }

    layout := HorizontalLayout {
        padding-left: 16px;
        padding-right: 12px;
        spacing: 16px;

        label := Text {
            text <=> root.current-value;
            color: MaterialPalette.control-foreground;
            vertical-alignment: center;
            // FIXME after Roboto font can be loaded
            // font-family: MaterialFontSettings.body-large.font;
            font-size: MaterialFontSettings.body-large.font-size;
            font-weight: MaterialFontSettings.body-large.font-weight;
            accessible-role: none;
        }

        icon := Image {
            width: 24px;
            height: 24px;
            y: (parent.height - self.height) / 2;
            source: Icons.expand-more;
            colorize: MaterialPalette.control-foreground;
            accessible-role: none;
        }
    }

    popup := PopupWindow {
        x: 0;
        y: root.height;
        width: root.width;
        height: root.visible-items * MaterialSizeSettings.item-height;
        forward-focus: inner-fs;

        popup-container := Rectangle {
            background: MaterialPalette.alternate-background;
            drop-shadow-color: MaterialPalette.shadow;
            drop-shadow-blur: Elevation.level2;
            drop-shadow-offset-y: 1px;
            border-radius: 4px;
        }

        inner-fs := FocusScope {
            focus-changed-event => {
                base.popup-has-focus = self.has-focus;
            }
            key-pressed(event) => {
                return base.popup-key-handler(event);
            }

            ScrollView {
                VerticalLayout {
                    alignment: start;

                    for value[index] in root.model: ListItem {
                        item: { text: value };
                        is-selected: index == root.current-index;
                        has-hover: touch-area.has-hover;
                        pressed: touch-area.pressed;

                        touch-area := StateLayer {
                            clicked => {
                                base.select(index);
                            }
                        }
                    }
                }
            }
        }
    }
}
